package com.ld.security.common.shiro.anno.aop;

import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.util.AopUtil;
import com.ld.security.common.core.util.ReflectionUtil;
import com.ld.security.common.shiro.anno.CacheKey;
import com.ld.security.common.shiro.anno.RoleKey;
import com.ld.security.common.shiro.config.ShiroProperties;
import io.swagger.annotations.Api;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;

@Component
@Aspect
@Order(5)
public class CacheAop {

    @Autowired
    CacheManager cacheManager;

    @Autowired
    ShiroProperties shiroProperties;

    @Pointcut("@annotation(com.ld.security.common.shiro.anno.CacheKey)")
    public void aop() {

    }




   @Around("aop()")
    public Object doAroundAdvice(ProceedingJoinPoint pjp) throws Throwable{
        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();
        CacheKey cacheKey =  AnnotationUtils.findAnnotation(method, CacheKey.class);
        Cache cache =  cacheManager.getCache(cacheKey.cacheName());
        Map map =  AopUtil.getParams(pjp);
        String key = ReflectionUtil.invokeGetter(map,cacheKey.key());
        Object v = null;
        switch (cacheKey.cacheType()){
            case query:{
                v = cache.get(key);
                if(v == null){
                    v =  pjp.proceed();
                    cache.put(key,v);
                }
                break;
            }
            case remove:{
                v =  pjp.proceed();
                cache.remove(key);
                break;
            }
            case put:{
               v =  pjp.proceed();
                cache.put(key,v);
                break;
            }
        }
        return v;
    }



}
